package cn.apthink.schedule;

import java.util.List;
import java.util.stream.Collectors;

import cn.apthink.utility.Util;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class EvaluationHelper {
	private Evaluation evaluation;

	public void evaluation(List<PlanKPI> plans) {
		double maxEfficiency = plans.stream().map(PlanKPI::getEfficiency).max((a, b) -> a.compareTo(b)).get();
		// David：指定指标权重积分升位（10*），避免缺省积分计算掩盖指标，
		// 如：未开启平衡生产时临近交期计算，方案积分延误计划数计算
		plans.forEach(x -> {
			if (evaluation.getContinueWeight() > 0 && x.isContinueProduct()) {
				if (evaluation.getContinueWeight()<4)
					x.setScore(x.getScore() + 10 * evaluation.getContinueWeight());
				else
					x.setScore(x.getScore() + 10 * 10 * evaluation.getContinueWeight());
			}
			if (evaluation.getEfficiencyWeight() > 0) {
				if (x.getEfficiency() >= maxEfficiency) {
					if (evaluation.getEfficiencyWeight()<4)
						x.setScore(x.getScore() + 10 * evaluation.getEfficiencyWeight());
					else
						x.setScore(x.getScore() + 10 * 10 * evaluation.getEfficiencyWeight());
					x.setMaxEfficiency(true);
				} else
					x.setMaxEfficiency(false);
			}
			if (evaluation.getDeliveryWeight() > 0 && x.isDelay()) {
				if (evaluation.getDeliveryWeight()<4)
					x.setScore(x.getScore() - 10 * evaluation.getDeliveryWeight() * x.getDelayDay());
				else
					x.setScore(x.getScore() - 10 * 10 * x.getDelayDay());
			}
			if (evaluation.getEarliestWeight() > 0 && x.isEarliest()) {
				if (evaluation.getEarliestWeight()<4)
					x.setScore(x.getScore() - 10 * evaluation.getEarliestWeight() * x.getEarliestDay());
				else
					x.setScore(x.getScore() - 10 * 10 * x.getEarliestDay());
			}
			// 不开启平衡生产时，无延误计划优先考虑临近交期（提前多得分少），有延误时不计算
//			if (!evaluation.isBalance() && !x.isDelay()) {
//				x.setScore(x.getScore() + x.getDelayDay());
//			}
			if (!evaluation.isBalance()) {
				x.setScore(x.getScore() - Math.abs(x.getDelayDay()));
			}
		});
	}

	public PlanKPI selectDepartment(List<PlanKPI> pks) {
		evaluation(pks);
		long maxScore = pks.stream().map(PlanKPI::getScore).max((a, b) -> a.compareTo(b)).get();
		List<PlanKPI> selectPlans = pks.stream().filter(x -> {
			return x.getScore() == maxScore;
		}).collect(Collectors.toList());
		if (selectPlans.size() > 1) {
			int index = Util.randInt(0, selectPlans.size());
			return selectPlans.get(index);
		} else {
			return selectPlans.get(0);
		}
	}

	public int getContinueDays() {
		return evaluation.getContinueDays();
	}

	public static EvaluationHelper testData() {
		EvaluationHelper helper = new EvaluationHelper();
		helper.setEvaluation(Evaluation.testData());
		return helper;
	}

}
